package com.sy.notice;

import com.alibaba.fastjson.JSON;
import com.sy.notice.biz.eventnotice.SendMsg;
import com.sy.notice.msg.TextMessage;
import com.sy.notice.util.HttpClientUtil;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.util.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.function.Supplier;

/**
 * @author 舒祥
 * @date 2022-01-16 10:36
 * @desc
 */
public class SendMsgToDingTalk implements SendMsg<Boolean> {


    private static String dingTalkUrl = "https://oapi.dingtalk.com/robot/send?";


    public boolean sendMsg(Object msg, String accessToken, String secret) throws Exception {
        String ddUrl = dingTalkUrl + "access_token=" + accessToken;
        if (!StringUtils.isEmpty(secret)) {
            Long timestamp = System.currentTimeMillis();
            String sign = getSign(secret, timestamp);
            ddUrl = ddUrl + "&timestamp=" + timestamp + "&sign=" + sign;
        }
        HttpClientUtil httpClientUtil = new HttpClientUtil();
        byte[] bytes = httpClientUtil.doJsonPostBytes(ddUrl, msg);
        String result = new String(bytes, StandardCharsets.UTF_8);
        Map map = JSON.parseObject(result, Map.class);
        Integer errcode = (Integer) map.get("errcode");
        if (errcode != 0) {
            throw new RuntimeException("request dingTalk errorcode:" + errcode + "errmsg:" + map.get("errmsg"));
        }
        return true;
    }


    public String getSign(String secret, Long timestamp) throws Exception {
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        return sign;
    }


    public static void main(String[] args) throws Exception {
        String msg = "{\n" +
                "    \"at\": {\n" +
                "        \"atMobiles\":[\n" +
                "            \"xxx\"\n" +
                "        ],\n" +
                "        \"atUserIds\":[\n" +
                "            \"user123\"\n" +
                "        ],\n" +
                "        \"isAtAll\": false\n" +
                "    },\n" +
                "    \"text\": {\n" +
                "        \"content\":\"我就是我, @xxx 是不一样的烟火\"\n" +
                "    },\n" +
                "    \"msgtype\":\"text\"\n" +
                "}";

        TextMessage textMessage = JSON.parseObject(msg, TextMessage.class);

        SendMsgToDingTalk sendMsgToDingTalk = new SendMsgToDingTalk();

        boolean b = sendMsgToDingTalk.sendMsg(textMessage, "xxx", "xxx");

        System.out.println(b);

    }


    @Override
    public Boolean sendMsg(Supplier msgSupplier, Supplier paramsSupplier) throws Exception {
        Map params = (Map) paramsSupplier.get();
        Object msg = msgSupplier.get();
        String accessToken = (String) params.get("accessToken");
        String secret = (String) params.get("secret");
        String ddUrl = dingTalkUrl + "access_token=" + accessToken;
        if (!StringUtils.isEmpty(secret)) {
            Long timestamp = System.currentTimeMillis();
            String sign = getSign(secret, timestamp);
            ddUrl = ddUrl + "&timestamp=" + timestamp + "&sign=" + sign;
        }
        HttpClientUtil httpClientUtil = new HttpClientUtil();
        byte[] bytes = httpClientUtil.doJsonPostBytes(ddUrl, msg);
        String result = new String(bytes, StandardCharsets.UTF_8);
        Map map = JSON.parseObject(result, Map.class);
        Integer errcode = (Integer) map.get("errcode");
        if (errcode != 0) {
            throw new RuntimeException("request dingTalk errorcode:" + errcode + "errmsg:" + map.get("errmsg"));
        }
        return true;
    }
}
